package ua.kpi.fpm.km61.strat.sp.st;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;

public class Block {

	private BlockType type;
	private ArrayList<Block> inner = new ArrayList<Block>();
	private Set<Symbol> symbols = new LinkedHashSet<Symbol>();
	private int level;
	private int firstIndex;
	private int lastIndex;
	private Block outer;
	private String name = "";
	
	public Block() {
		super();
		
	}
	
	public BlockType getType() {
		return type;
	}
	public void setType(BlockType type) {
		this.type = type;
	}


	/**
	 * @return the symbols
	 */
	public Set<Symbol> getSymbols() {
		return symbols;
	}



	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public ArrayList<Block> getInner() {
		return inner;
	}

	public void setInner(ArrayList<Block> inner) {
		this.inner = inner;
	}
	
	public void addInner(Block innerBlock) {
		this.inner.add(innerBlock);
	}
	
	public void addSymbol(Symbol symbol) {
		this.symbols.add(symbol);
	}

	public int getFirstIndex() {
		return firstIndex;
	}

	public void setFirstIndex(int firstIndex) {
		this.firstIndex = firstIndex;
	}

	public int getLastIndex() {
		return lastIndex;
	}

	public void setLastIndex(int lastIndex) {
		this.lastIndex = lastIndex;
	}

	public Block getOuter() {
		return outer;
	}

	public void setOuter(Block outer) {
		this.outer = outer;
	}


	@Override
	public String toString() {
		StringBuilder blank = new StringBuilder();
		for(int i=0; i<=this.level*2; i++){
			blank.append(" ");
		}
		String b = blank.toString();
		StringBuilder sb = new  StringBuilder(); 
		sb.append("\n" + b + this.getType() + this.getName() +" ("+this.getLevel()+")");
		sb.append("\n" + b + "   firstLexem=" + (firstIndex+1) + ", lastLexem=" + (lastIndex + 1)) ;
		sb.append("\n" + b + "   " + "symbols:");
		for(Symbol s: this.symbols){
			sb.append("\n" + b + "    " + s);
		}
		for(Block bl: this.getInner()){
			sb.append("\n" + b + "   " + bl);
		}
		sb.append("\n" + b + "}");
		return sb.toString();
	}
	
	public String symbols() {
		StringBuilder sb = new StringBuilder();
		for(Symbol s: this.symbols){
			sb.append("\n" + s + " ["+ s.getFirstIndex() + " " + s.getLastIndex() +"] Block=" + s.getBlockType() + " Level" + "("+this.getLevel()+") "
					+ "public=" + !s.isPrivateSymbol());
		}
		for(Block bl: this.getInner()){
			sb.append(bl.symbols());
		}
		return sb.toString();
	}
	
	public  Symbol find(String name){
		Symbol symbol = null;
		for (Symbol sym: this.getSymbols()){
			if(sym.getName().equals(name)){
				symbol = sym;
			} 
		}
			if ((symbol == null) && this.getOuter() != null){
				symbol = this.getOuter().find(name);
			} 
		return symbol;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	
}
